/*
 * test15.cc -- check illegal inputs for the method "thread_sleep". 

 *
 * Output should be:
test15:
--------------

(6 error messages that you print {SHOULD NOT INCLUDE "FAIL:..."}.)

OK

 */

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <map>
#include <list>
#include "uthreads.hh"

int millisecsToSleep=100;


void illegalTime()
{
	int id = thread_gettid();
	if( thread_sleep(id, -1)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when it gets negative time");
		exit(0);
	}

	if( thread_sleep(id, -100)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when it gets negative time");
		exit(0);
	}

	thread_terminate(id);
}

void suspendFunc() //id =2
{
	
	if( thread_sync(3, 3)==-1){
		printf("FAIL: the method thread_sync failed");
		exit(0);
	}

	printf("FAIL: SUSPENDED thread become READY without any reason");
	exit(0);
}


void sleepFuncSuc()//its id is 3
{

   	int id = thread_gettid();
	if (thread_sleep(id, millisecsToSleep)==-1){
		printf("FAIL: the method thread_sync doesn't return error when you call it from the main");
		exit(0);
	}
	thread_terminate(id);
}


void sleepFuncFail()//its id is 4
{

   	int id = thread_gettid();
	if (thread_sleep(id, millisecsToSleep)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when other thread is sleeping");
		exit(0);
	}
	thread_terminate(id);
}



void empty() //id =1
{

 	int id = thread_gettid();
	thread_terminate(id);
}


int main(int argc, char **argv)
{
    printf("test15:\n--------------\n");
    thread_lib_init();
	
	//try to sleep the main
	if( thread_sleep(0, 1000)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when you call it from the main");
		exit(0);
	}

	//try to sleep non-exist thread
	if( thread_sleep(1, 1000)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when there is no thread with the given id");
		exit(0);
	}
	thread_spawn(empty);//its id is 1
	//try to sleep terminated thread
	if( thread_sleep(1, 1000)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when tid belong to terminated thread");
		exit(0);
	}

	//try to sleep a suspend thread
	thread_spawn(suspendFunc);//its id is 2
	if (thread_sleep(2, millisecsToSleep)!=-1){
		printf("FAIL: the method thread_sleep doesn't return error when the given thread is SUSPENEDED");
		exit(0);
	}


	//call two threads to sleep simultaneously
	thread_spawn(sleepFuncSuc);//its id is 3
 	thread_spawn(sleepFuncFail);//its id is 4


	printf ("here\n");
	//wait the sleep will end..
	while ( thread_get_time_until_wakeup(3) !=0 ){}

	printf ("here\n\n");
	thread_spawn(illegalTime);

	printf ("OK");
    thread_terminate(0);
    return 0;
}

